<template>
    <div class="login_container">
        <!-- v-model：控制对话框显示隐藏，
            这个属性不建议设置到本组件中，
            因为对话框的显示隐藏，可能是由这个组件的父组件，兄弟组件，子组件等来控制，
            所以定义到仓库中是最合适的 
        -->
        <!-- title：对话框左上角标题 -->
        <el-dialog v-model="userStore.visiable" title="用户登录">
            <!-- 对话框身体部分的结构 -->
            <el-row>
                <!-- 左侧结构：手机号码登录、微信扫一扫登录 -->
                <el-col :span="12">
                    <div class="login">
                        <div v-show="scene == 0">
                            <el-form :model="loginParam" :rules="rules" ref="form">
                                <el-form-item prop="phone">
                                    <el-input placeholder="请输入手机号码" 
                                        :prefix-icon="User"
                                        v-model="loginParam.phone">
                                    </el-input>
                                </el-form-item>
                                <el-form-item prop="code">
                                    <el-input placeholder="请输入手机验证码" 
                                    :prefix-icon="Lock"
                                    v-model="loginParam.code"></el-input>
                                </el-form-item>
                                <el-form-item>
                                    <el-button 
                                        :disabled="!isPhone || flag ? true : false"
                                        @click="getCode()">
                                        <CountDown v-if="flag" :flag="flag" @getFlag="getFlag" />
                                        <span v-else>获取验证码</span>
                                    </el-button>
                                </el-form-item>
                            </el-form>
                            <el-button style="width: 100%;" 
                                       type="primary" size="default"
                                       :disabled="!isPhone || loginParam.code.length < 6 ? true: false"
                                       @click="login()"
                                       >
                                       用户登录
                            </el-button>
                            <div class="bottom" @click="changeScene">
                                <p>微信扫码登录</p>
                                <svg t="1698303760127" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4074" width="32" height="32"><path d="M664.250054 368.541681c10.015098 0 19.892049 0.732687 29.67281 1.795902-26.647917-122.810047-159.358451-214.077703-310.826188-214.077703-169.353083 0-308.085774 114.232694-308.085774 259.274068 0 83.708494 46.165436 152.460344 123.281791 205.78483l-30.80868 91.730191 107.688651-53.455469c38.558178 7.53665 69.459978 15.308661 107.924012 15.308661 9.66308 0 19.230993-0.470721 28.752858-1.225921-6.025227-20.36584-9.521864-41.723264-9.521864-63.862493C402.328693 476.632491 517.908058 368.541681 664.250054 368.541681zM498.62897 285.87389c23.200398 0 38.557154 15.120372 38.557154 38.061874 0 22.846334-15.356756 38.156018-38.557154 38.156018-23.107277 0-46.260603-15.309684-46.260603-38.156018C452.368366 300.994262 475.522716 285.87389 498.62897 285.87389zM283.016307 362.090758c-23.107277 0-46.402843-15.309684-46.402843-38.156018 0-22.941502 23.295566-38.061874 46.402843-38.061874 23.081695 0 38.46301 15.120372 38.46301 38.061874C321.479317 346.782098 306.098002 362.090758 283.016307 362.090758zM945.448458 606.151333c0-121.888048-123.258255-221.236753-261.683954-221.236753-146.57838 0-262.015505 99.348706-262.015505 221.236753 0 122.06508 115.437126 221.200938 262.015505 221.200938 30.66644 0 61.617359-7.609305 92.423993-15.262612l84.513836 45.786813-23.178909-76.17082C899.379213 735.776599 945.448458 674.90216 945.448458 606.151333zM598.803483 567.994292c-15.332197 0-30.807656-15.096836-30.807656-30.501688 0-15.190981 15.47546-30.477129 30.807656-30.477129 23.295566 0 38.558178 15.286148 38.558178 30.477129C637.361661 552.897456 622.099049 567.994292 598.803483 567.994292zM768.25071 567.994292c-15.213493 0-30.594809-15.096836-30.594809-30.501688 0-15.190981 15.381315-30.477129 30.594809-30.477129 23.107277 0 38.558178 15.286148 38.558178 30.477129C806.808888 552.897456 791.357987 567.994292 768.25071 567.994292z" fill="#5D5D5D" p-id="4075"></path></svg>
                            </div>
                        </div>
                        <div class="webchat" v-show="scene == 1">
                            <!-- 在这个容器当中显示微信扫码登录的页面 -->
                            <div id="login_container">
                            </div>
                            <div class="phone" @click="handler">
                                <p>手机短信验证码登录</p>
                                <svg t="1700204925114" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4093" width="16" height="16"><path d="M820.409449 797.228346q0 25.19685-10.07874 46.866142t-27.716535 38.299213-41.322835 26.204724-50.897638 9.574803l-357.795276 0q-27.212598 0-50.897638-9.574803t-41.322835-26.204724-27.716535-38.299213-10.07874-46.866142l0-675.275591q0-25.19685 10.07874-47.370079t27.716535-38.80315 41.322835-26.204724 50.897638-9.574803l357.795276 0q27.212598 0 50.897638 9.574803t41.322835 26.204724 27.716535 38.80315 10.07874 47.370079l0 675.275591zM738.771654 170.330709l-455.559055 0 0 577.511811 455.559055 0 0-577.511811zM510.992126 776.062992q-21.165354 0-36.787402 15.11811t-15.622047 37.291339q0 21.165354 15.622047 36.787402t36.787402 15.622047q22.173228 0 37.291339-15.622047t15.11811-36.787402q0-22.173228-15.11811-37.291339t-37.291339-15.11811zM591.622047 84.661417q0-8.062992-5.03937-12.598425t-11.086614-4.535433l-128 0q-5.03937 0-10.582677 4.535433t-5.543307 12.598425 5.03937 12.598425 11.086614 4.535433l128 0q6.047244 0 11.086614-4.535433t5.03937-12.598425z" p-id="4094"></path></svg>
                            </div>
                        </div>
                    </div>
                </el-col> 
                <!-- 右侧 -->
                <el-col :span="12">
                    <div class="leftContent">
                        <div class="top">
                            <div class="item">
                                <img src="../../assets/images/code_app.png" alt="">
                                <svg t="1698303760127" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4074" width="16" height="16"><path d="M664.250054 368.541681c10.015098 0 19.892049 0.732687 29.67281 1.795902-26.647917-122.810047-159.358451-214.077703-310.826188-214.077703-169.353083 0-308.085774 114.232694-308.085774 259.274068 0 83.708494 46.165436 152.460344 123.281791 205.78483l-30.80868 91.730191 107.688651-53.455469c38.558178 7.53665 69.459978 15.308661 107.924012 15.308661 9.66308 0 19.230993-0.470721 28.752858-1.225921-6.025227-20.36584-9.521864-41.723264-9.521864-63.862493C402.328693 476.632491 517.908058 368.541681 664.250054 368.541681zM498.62897 285.87389c23.200398 0 38.557154 15.120372 38.557154 38.061874 0 22.846334-15.356756 38.156018-38.557154 38.156018-23.107277 0-46.260603-15.309684-46.260603-38.156018C452.368366 300.994262 475.522716 285.87389 498.62897 285.87389zM283.016307 362.090758c-23.107277 0-46.402843-15.309684-46.402843-38.156018 0-22.941502 23.295566-38.061874 46.402843-38.061874 23.081695 0 38.46301 15.120372 38.46301 38.061874C321.479317 346.782098 306.098002 362.090758 283.016307 362.090758zM945.448458 606.151333c0-121.888048-123.258255-221.236753-261.683954-221.236753-146.57838 0-262.015505 99.348706-262.015505 221.236753 0 122.06508 115.437126 221.200938 262.015505 221.200938 30.66644 0 61.617359-7.609305 92.423993-15.262612l84.513836 45.786813-23.178909-76.17082C899.379213 735.776599 945.448458 674.90216 945.448458 606.151333zM598.803483 567.994292c-15.332197 0-30.807656-15.096836-30.807656-30.501688 0-15.190981 15.47546-30.477129 30.807656-30.477129 23.295566 0 38.558178 15.286148 38.558178 30.477129C637.361661 552.897456 622.099049 567.994292 598.803483 567.994292zM768.25071 567.994292c-15.213493 0-30.594809-15.096836-30.594809-30.501688 0-15.190981 15.381315-30.477129 30.594809-30.477129 23.107277 0 38.558178 15.286148 38.558178 30.477129C806.808888 552.897456 791.357987 567.994292 768.25071 567.994292z" fill="#5D5D5D" p-id="4075"></path></svg>
                                <p>微信扫一扫关注</p>
                                <p>“快速预约挂号”</p>
                            </div>
                            <div class="item">
                                <img src="../../assets/images/code_login_wechat.png" alt="">
                                <svg t="1698304193274" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5353" width="16" height="16"><path d="M798.723234 174.782745c0-60.576657-49.106418-109.683075-109.683075-109.683075l-354.708628 0c-60.576657 0-109.683075 49.106418-109.683075 109.683075l0 673.980161c0 60.576657 49.106418 109.683075 109.683075 109.683075l354.708628 0c60.576657 0 109.683075-49.106418 109.683075-109.683075L798.723234 174.782745zM264.557398 237.015112l494.256894 0 0 529.049305-494.256894 0L264.557398 237.015112zM334.356091 105.008612 689.016623 105.008612c38.548968 0 69.798692 31.249725 69.798692 69.798692l0 22.298865-494.256894 0 0-22.298865C264.557398 136.25936 295.807123 105.008612 334.356091 105.008612zM689.016623 918.53704 334.356091 918.53704c-38.548968 0-69.798692-31.249725-69.798692-69.798692l0-43.788296 494.256894 0 0 43.788296C758.814292 887.287315 727.564567 918.53704 689.016623 918.53704z" fill="#272636" p-id="5354"></path><path d="M513.173732 829.943282c-16.70752 0-30.30112 13.5936-30.30112 30.30112 0 16.70752 13.5936 30.30112 30.30112 30.30112s30.299073-13.5936 30.299073-30.30112C543.472805 843.536882 529.881253 829.943282 513.173732 829.943282z" fill="#272636" p-id="5355"></path></svg>
                                <p>扫一扫下载</p>
                                <p>“预约挂号”APP</p>
                            </div>
                            
                        </div>
                    </div>
                    <p class="tip">尚医通官方指定平台</p>
                    <p class="tip">快速挂号，安全放心</p>
                </el-col> 
            </el-row>

            <!-- 底部插槽 -->
            <template #footer>
                <el-button type="primary" size="default" @click="closeDialog()">关闭窗口</el-button>
            </template>
        </el-dialog>
    </div>    
</template>

<script setup lang="ts">
//引入微信扫码登录参数请求
import {reqWxLogin} from '@/api/hospital';

//引入倒计时组件
import CountDown from '../countdown/index.vue';

import {ref, reactive, computed, watch} from 'vue'

//引入图标
import {User, Lock} from '@element-plus/icons-vue';

import type {WXLoginResponseData} from '@/api/hospital/type';

import { useRoute, useRouter } from 'vue-router';

//获取 user 仓库的数据（visiable）数据可以控制 login 组件的对话框的显示与隐藏
import useUserStore from '@/store/modules/user';
import { ElMessage } from 'element-plus';
let userStore = useUserStore();

//获取路由器对象
let $route = useRoute();
let $router = useRouter();

let scene = ref<number>(0);//0:手机号码登录；1:微信扫码登录
//点击微信扫描登录，微信小图标切换为微信扫码登录
const changeScene = async() => {
    //切换场景为1
    scene.value = 1;
    //发请求获取微信扫码二维码需要的参数
    //咋们在向硅谷学校的服务器发请求，获取微信扫码登录页面参数
    //还需要携带一个参数：告诉学校服务器授权成功后以后重定向项目某一个页面
    let redirect_URL = encodeURIComponent(window.location.origin + '/wxlogin');
    let result:WXLoginResponseData = await reqWxLogin(redirect_URL);
    //生成微信扫描登录的二维码页面
     //@ts-ignore
     new WxLogin({
        self_redirect: true,//true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri
        id: "login_container",//显示二维码容器 ID
        appid: result.data.appid,//应用的唯一标识 appid
        scope: "snsapi_login",//代表微信扫描登录的页面已经授权了，应用授权的作用域
        redirect_uri: result.data.redirectUri,//填写授权回调域的路径，就是用户授权成功以后微信服务器向公司后台推送 code 地址
        state: result.data.state,//state 就学校服务器重定向地址，携带用户的信息
        style: "black",//文字颜色
        href: "" //自定义样式链接       
    });
};

//收集表单数据，收集手机号码
let loginParam = reactive({
    phone: '',//收集手机号码
    code:'' //收集对应的验证码
});
//计算出当前表单元素收集的内容是否是手机号码
let isPhone = computed(() => {
    //手机号码的正则表达式
    const reg = /^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/;
    //返回相应的 boolean ，true:手机号码，false:不是手机号码
    return reg.test(loginParam.phone);
});

//定义一个响应式数据去控制倒计时组件的显示与隐藏
//flag，true:开始倒计时，false:并非倒计时
let flag = ref<boolean>(false);

//获取验证码按钮的回调
const getCode = async() => {
    //解决 element-plus 按钮禁用还能点击的问题
    if(!isPhone.value || flag.value) return;

    //开启倒计时模式，倒计时组件显示出来
    flag.value = true;

    try{
        //获取验证码成功
        //通知 Pinia 仓库存储验证码
        await userStore.getCode(loginParam.phone);
        loginParam.code = userStore.code;
    }catch(error) {
        //获取验证码失败
        ElMessage({
            type:'error',
            message: (error as Error).message
        });
    }
}

//计数器子组件绑定的自定义事件
//当倒计时为 0 的时候，通知父组件倒计时组件应该隐藏
const getFlag = (val:boolean) => {
    //倒计时模式结束
    flag.value = val;
};

//获取 form 组件实例
let form = ref<any>();

//点击用户登录按钮的回调
const login = async() => {
    //保证表单校验的两项都符合条件
    await form.value.validate();

    //发起登录请求
    //登录请求成功，顶部组件需要展示用户名字，对话框关闭
    //登录请求失败，弹出对应登录失败的错误信息
    try {
        //用户登录成功
        await userStore.userLogin(loginParam);
        //关闭对话框
        userStore.visiable = false;

        //获取 url 的 query 参数
        //存储登录前想去而被登录限制的 url
        let redirect = $route.query.redirect;
        if(redirect) {
            $router.push(redirect as string);
        } else {
            $router.push('./home');
        }
    } catch (error) {
        ElMessage({
            type: 'error',
            message: (error as Error).message
        });
    }
};

//自定义校验规则：手机号码的自定义校验规则
//@ts-ignore
const validatorPhone = (rule: any, value: any, callback: any) => {
    //rule:表单校验规则对象
    //value:当前的文本内容
    //callback:回调函数
    //手机号码的正则表达式
    const reg = /^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/;
    //返回相应的 boolean ，true:手机号码，false:不是手机号码
    if(reg.test(value)) {
        callback();
    } else {
        callback(new Error('请输入正确的手机号码'));
    }
};
//自定义校验规则：验证码的自定义校验规则
//@ts-ignore
const validatorCode = (rule: any, value: any, callback: any) => {
    //rule:表单校验规则对象
    //value:当前的文本内容
    //callback:回调函数
    //手机号码的正则表达式
    const reg = /^\d{6}$/;
    //返回相应的 boolean ，true:匹配，false:不匹配
    if(reg.test(value)) {
        callback();
    } else {
        callback(new Error('请输入正确的验证码格式'));
    }
};

//表单校验的规则对象
const rules =  {
    //手机号码验证规则
    //required:代表当前字段务必进行校验
    //message:代表校验错误的提示信息
    //trigger:代表表单校验触发的时机，change:文本发生变化的时候校验，blur:失去焦点的时候校验
    //min:代表最小位数
    //max:代表最大位数
    // phone: [{required:true, message :'手机号码务必11位',trigger:'blur', min:11}],
    // code:[{required:true, message :'验证码务必6位',trigger:'blur',min:6}]
    phone: [{trigger:'change', validator:validatorPhone}],
    code: [{trigger:'change', validator:validatorCode}]
};

// //对话框关闭事件的回调
// const close = () => {
//     //清空收集的数据
//     Object.assign(loginParam,{phone:'',code:''});
//     //清除上一次校验的结果
//     form.value.resetFields();
// };

//关闭窗口的回调
const closeDialog = () => {
    userStore.visiable = false;
    //close();
};

//点击手机短信验证码盒子的回调
const handler = () => {
    scene.value = 0;
}

//监听场景的数据
watch(() => scene.value, (val:number) => {
    //说明是扫码
    if(val === 1) {
        userStore.queryState();
    }
});
</script>

<script lang="ts">
export default {
    name: 'login'
}
</script>

<style scoped lang="scss">
.login_container {
    //深度选择器
    ::v-deep(.el-dialog__body) {
        border-top: 1px solid #ccc;
        border-bottom: 1px solid #ccc;
    }

    .login {
        padding: 20px;
        border: 1px solid #ccc;

        .webchat {
            display: flex;
            flex-direction: column;
            align-items: center;

            .phone {
                display: flex;
                flex-direction: column;
                align-items: center;
                p{
                    margin: 10px 0;
                }
            }
        }
    }

    .bottom {
        display: flex;
        flex-direction: column;
        align-items: center;

        p {
            margin: 10px 0px;
        }
    }

    .leftContent {
        .top {
            display: flex;
            justify-content: space-around;

            .item {
                display: flex;
                flex-direction: column;
                align-items: center;
                
                img {
                    width: 130px;
                    height: 130px;
                }

                p {
                    margin: 5px 0px;
                }
            }
        }
    }

    .tip {
        text-align: center;
        margin: 20px 0px;
        font-size: 20px;
        font-weight: 900;
    }
} 
</style>

